package l2capRtpSender;

/**
 * @author Alex
 * @version 0.2
 * Questa classe ricever dal componente dedicato alla "new client" inquiry, una lista di dispositivi Bluetooth
 * raggiungibili, e con ognuno di essi richieder di stabilire una connessione
 * RTP,per la trasmissione di una file Audio.
 * Inoltre alla ricezione del pacchetto di aggiornamento della lista dispositivi
 * verificher quali sono gi stati attivati e quali no, nel secondo caso attivandoli; mentre
 * se si verificasse la condizione di una dispositivo attivato ma non presente nella lista,
 * si interrogher quest'ultimo verificandone lo stato e se non attivo verr disattivato,
 * aggiornando ad ognuno dei passi descritti precedentemente una hastable.
 */

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;

import l2capRtpSender.SessionStreamTransmitter.TransmissionClosedEvent;
import l2capRtpSender.SessionStreamTransmitter.TransmissionTerminatedEvent;


public class Gateway implements SSTransmitterListener{
	/**
	 * Creo la lista di tutti i thread trasmettitori attivi.
	 */
	Hashtable <String,Thread>activedThreadTransmitterTable = new Hashtable<String,Thread>();
	String path="file:/home/erond/Scrivania/RetiLS_project/media/lucio.wav";
	/**
	 * Simulo la lettura della lista di inquiry da File, ma potrebbe avvenire benissimo
	 * anche da socket.
	 * @throws FileNotFoundException
	 */
	public void readInquiry() throws FileNotFoundException{
	Object f = null;
	InputStream inquiry = new FileInputStream((String) f);
	inquiry = new BufferedInputStream(inquiry);
	String btClientAddressList;
	int bytesRead; 
	byte[] buffer = new byte[512];

	while(true){
	try {
		bytesRead = inquiry.read(buffer);
        btClientAddressList = new String(buffer,0, bytesRead);
        activeTransmitter(btClientAddressList);
	} catch (IOException e) {
		e.printStackTrace();
	}
	}
	}
	/**
	 * @param btClientAddressList
	 * Verifico quali sono gli elementi NON PRESENTI in lista e se DISATTIVI ne eseguo subito
	 * l'attivazione, mentre se ATTIVI ne verifico lo stato ed eventualmente ne termino 
	 * l'esecuzione.
	 */
	public void activeTransmitter(String btClientAddressList){
		SessionStreamTransmitter  threadTransmitter = null;
		String delims = ",";
		String[] btAddress = btClientAddressList.split(delims);	
		/**
		 * Prima controllo da lista nuova a vecchia [1,3,5] -> [1,3,7,8] in questo caso inserisco ed attivo 5.
		 * Dopo controller da vecchia aggiornata a nuova [1,3,5,7,8] -> [1,3,5] e controller cos lo stato di 7,8. 
		 */
		for (int i = 0; i < btAddress.length; i++){	
			if(!activedThreadTransmitterTable.containsKey(btAddress [i])){
				threadTransmitter =  new SessionStreamTransmitter(path,btAddress [i]);
			    threadTransmitter.start();
			    threadTransmitter.addSSTransmitterListener(this);
				activedThreadTransmitterTable.put(btAddress [i],threadTransmitter);
			}
			else System.out.println("Client gi attivato"); 
		}
		Enumeration<String> activeClient = activedThreadTransmitterTable.keys();
		while( activeClient.hasMoreElements() ){
			int k = 0;
			String clientActived = (String)activeClient.nextElement();
			for(int j = 0; j < btAddress.length; j++){
				if(clientActived!=btAddress[j]){
					/**
					 *Con la variabile k, conto i client con MAC diverso da quello selezionato,
					 *se il loro numero  uguale alla lista data in ingresso, verifico
					 *se il client corrente NON PRESENTE  ancora in esecuzione.
					 */
					k++;
					}
				if(k==btAddress.length){
				checkTransmittersActivity(clientActived);
				}
				}
			}

		}	
	/**
	 * @param clientActived
	 * Prendo in ingresso la chiave del thread di Trasmissione da verificare,
	 * ne controllo lo stato e se non in trasmissione, lo disattivo ed aggiorno
	 * la activedThreadTable.
	 */
	public void checkTransmittersActivity(String clientActived){
		SessionStreamTransmitter checkThread = (SessionStreamTransmitter) activedThreadTransmitterTable.get(clientActived);
		//Se la trasmissione risulta non attiva off= FALSE
		if(!checkThread.getTrasmissionState()){
			activedThreadTransmitterTable.remove(clientActived);
			System.out.println("Thread di trasmissione Rimosso.."); 
		}

	}
	/**
	 * Questo metodo sar utilizzato per cambiare ad ogni thread trasmettitore attivo
	 * il formato di codifica dell' output Stream.
	 * Data in ingresso la lista di thread attivi, vengono estratti e per ognuno viene
	 * richiamato il metodo audioBtTransmitter.setTrackFormat(1), della classe di trasmissione.
	 * @param activedThreadTransmitterTable
	 * @throws IOException 
	 */
	public void changeCoding() throws IOException{
//	Enumeration<String> activeClient = activedThreadTransmitterTable.keys();
//    while( activeClient.hasMoreElements() ){
//	String clientActived = (String)activeClient.nextElement();
//	OutputTransmitter checkThread = (OutputTransmitter) activedThreadTransmitterTable.get(clientActived);
//	//PRIMA PROVA BLOCCANDO IL PROCESSO e SETTANDO UN NUOVO FORMATO.
//  	if(checkThread==null)System.out.println("[Thread NULLO]");
//  	System.out.println("Nome del Thread: "+ checkThread.getName());
//  	System.out.println("Stato del thread: "+ checkThread.getState());

  	
//	checkThread.audioBtTransmitter.setTrackFormat(1);
	//SECONDA PROVA BLOCCANDO LO STREAM E RICREANDO UNO NUOVO DATASOURCE
	//checkThread.audioBtTransmitter.recodeDataOutput();
//	  }
	}
	
	
	
	/** Gestione degli eventi dei vari trasmettitori.**/
	
	public void transmissionClosed(TransmissionClosedEvent evt) {
		// TODO Auto-generated method stub
		
	}
	public void transmissionTerminated(TransmissionTerminatedEvent evt) {
		activedThreadTransmitterTable.remove(evt.getBtAddress());
		System.out.println("Client "+ evt.getBtAddress() +" Rimosso."); 		
	}

	
	public static void main (String args[]) throws IOException {
		Gateway g = new Gateway();
	//	g.activeTransmitter("001693010A20,0016CB341D96");  
		g.activeTransmitter("0016CB341D96");  
		
	try {
		    Thread.currentThread().sleep(10000);
		} catch (InterruptedException ie) {
		}
      
	//	g.checkTransmittersActivity("0016CB341D96");	
		
	// Provo a resettare la codifica.	

	}

}